package top.honlnk.czuan.service.impl;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.honlnk.czuan.common.exception.CustomException;
import top.honlnk.czuan.common.utils.AliOSSUtil;
import top.honlnk.czuan.common.utils.BaiduDictUtil;
import top.honlnk.czuan.common.utils.SnowflakeIdUtil;
import top.honlnk.czuan.mapper.dict.DataOssUrlMapper;
import top.honlnk.czuan.mapper.partSpeech.AddPartSpeech;
import top.honlnk.czuan.pojo.bo.SymbolBo;
import top.honlnk.czuan.pojo.dto.add.AddTranslationDTO;
import top.honlnk.czuan.pojo.dto.dict.BaiduDictDTO;
import top.honlnk.czuan.pojo.entity.BaiduDict;
import top.honlnk.czuan.pojo.vo.GetBaiduDictVO;
import top.honlnk.czuan.service.AddService;
import top.honlnk.czuan.service.DictionaryService;
import top.honlnk.czuan.service.impl.module.get.GetPartSpeechSIModule;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class DictionaryServiceImpl implements DictionaryService {

    @Autowired
    private BaiduDictUtil baiduDictUtil;

    @Autowired
    private AliOSSUtil aliOSSUtil;

    @Autowired
    private AddService addService;

    @Autowired
    private GetPartSpeechSIModule getPartSpeechSIModule;

    @Autowired
    private AddPartSpeech addPartSpeech;

    @Autowired
    private DataOssUrlMapper dataOssUrlMapper;

    @Autowired
    private SnowflakeIdUtil snowflakeIdUtil;

    // 生成唯一id值
    private Integer makeOnlyId() {
        return snowflakeIdUtil.nextId();
    }

    @Override
    public List<GetBaiduDictVO> baiduDict(BaiduDictDTO baiduDictDTO) {

        List<GetBaiduDictVO> getBaiduDictVOList = new ArrayList<>();

        // 获取“百度机器翻译-文本翻译-词典版”的翻译结果
        JSONObject httpResponseData = baiduDictUtil.baiduDict(baiduDictDTO);// 翻译AP返回数据
        // 获取单词翻译结果
        JSONArray transResults = httpResponseData.getJSONObject("result").getJSONArray("trans_result");
        if (transResults.isEmpty()) throw new CustomException("没有查询到任何翻译结果");
        for (int i = 0; i < transResults.size(); i++) {

            JSONObject transResult = transResults.getJSONObject(i);
            if (!transResult.containsKey("dict") || !transResult.getJSONObject("dict").containsKey("word_result")) {
                // 在这里处理最基本得翻译结果
                String word = transResult.getStr("src");
                String baseTranslation = transResult.getStr("dst");

                JSONObject dictData = baiduDictUtil.getDictInfo(transResult);
                String dictDataOSSFileUrl = aliOSSUtil.uploadDictFile(word, dictData);

                JSONObject ttsData = baiduDictUtil.getTtsFile(transResult);
                Map<String, String> ttsDataOSSFileUrl = aliOSSUtil.uploadTtsFile(word, ttsData);

                GetBaiduDictVO getBaiduDictVO = GetBaiduDictVO.builder()
                        .word(word)
                        .baseTranslation(baseTranslation)
                        .symbols(new ArrayList<>())
                        .exchangeWords(new HashMap<>())
                        .dictFilePath(dictDataOSSFileUrl)
                        .ttsFilePath(ttsDataOSSFileUrl)
                        .build();
                getBaiduDictVOList.add(getBaiduDictVO);
                continue;
            }
            JSONObject dict = transResult.getJSONObject("dict");        // 词典返回数据（‘词典’不等于‘翻译API’）
            JSONObject wordResult = dict.getJSONObject("word_result");  // 单词查询结果
            JSONObject edict;       // 英文原版释义：所有解释均为英文，保留单词的原始语义。
//            JSONObject zdict;       // 中文版释义。(疑似已经弃用)
            JSONObject simpleMeans = new JSONObject(); // 简明释义：提供单词的核心中文翻译、考试标签及词形变化信息。
            JSONObject common;      // 单词的通用信息

            /*
              1. 获取单词本身
             */
            String word;
            word = transResult.getStr("src"); // 默认使用src初始化
            if (wordResult.containsKey("edict") && !wordResult.getStr("edict").isEmpty()) {
                edict = wordResult.getJSONObject("edict");
                String potentialWord = baiduDictUtil.getSrc(edict);
                if (potentialWord != null && !potentialWord.isEmpty()) {
                    word = potentialWord;
                }
            }

            /*
              2. 获取单词的基础翻译
             */
            String baseTranslation;
            baseTranslation = transResult.getStr("dst");
            if (wordResult.containsKey("common") && !wordResult.getStr("common").isEmpty()) {
                common = wordResult.getJSONObject("common");
                String potentialBaseTranslation = baiduDictUtil.getDst(common);
                if (potentialBaseTranslation != null && !potentialBaseTranslation.isEmpty()) {
                    baseTranslation = potentialBaseTranslation;
                }
            }

            /*
              3. 获取单词的简明释义主要信息：
             */
            if (wordResult.containsKey("simple_means") && !wordResult.getStr("simple_means").isEmpty()) {
                simpleMeans = wordResult.getJSONObject("simple_means");
            }

            /*
              3.1. 获取单词的符号相关：音标，词性
             */
            JSONArray symbols = new JSONArray();
            List<SymbolBo> symbolBoList = new ArrayList<>();
            if (simpleMeans.containsKey("symbols")) {
                symbols = simpleMeans.getJSONArray("symbols");
            }
            for (int j = 0; j < symbols.size(); j++) {
                SymbolBo symbolBo = new SymbolBo();
                JSONObject symbol = symbols.getJSONObject(j);
                /*
                    3.1.1. 获取单词的音标
                */
                Map<String, String>  phoneticSymbols = baiduDictUtil.getSymbols(symbol);
                symbolBo.setPhoneticSymbols(phoneticSymbols);
                /*
                    3.1.2. 获取单词的翻译
                */
                Map<String, List<String>> translationsMapList = baiduDictUtil.getTranslation(symbol);
                Map<String, Map<Integer, String>> translations = new HashMap<>();
                if (!translationsMapList.isEmpty()) {
                    List<AddTranslationDTO> TranslationPartIdList = translationsMapToAddTranslationDTOList(translationsMapList);
                     translations = addService.addTranslationAll(TranslationPartIdList);
                }
                symbolBo.setTranslations(translations);

                symbolBoList.add(symbolBo);
            }

            /*
              3.2. 获取单词的同义词
             */
            JSONObject exchange = new JSONObject();
            if (simpleMeans.containsKey("exchange")) {
                exchange = simpleMeans.getJSONObject("exchange");
            }

            Map<String, List<String>>  exchangeWords = baiduDictUtil.getExchange(exchange);


            /*
              4. 上传OSS
              4.1. 上传并获取单词翻译结果的文件OSS路径
             */
            JSONObject dictData = baiduDictUtil.getDictInfo(transResult);
            String dictDataOSSFileUrl = aliOSSUtil.uploadDictFile(word, dictData);

            /*
              4.2. 上传并获取单词读音文件的OSS路径
             */
            JSONObject ttsData = baiduDictUtil.getTtsFile(transResult);
            Map<String, String> ttsDataOSSFileUrl = aliOSSUtil.uploadTtsFile(word, ttsData);

            GetBaiduDictVO getBaiduDictVO = GetBaiduDictVO.builder()
                    .word(word)
                    .baseTranslation(baseTranslation)
                    .symbols(symbolBoList)
                    .exchangeWords(exchangeWords)
                    .dictFilePath(dictDataOSSFileUrl)
                    .ttsFilePath(ttsDataOSSFileUrl)
                    .build();
            getBaiduDictVOList.add(getBaiduDictVO);
        }

        /*
        持久化存储
         */
        List<BaiduDict> baiduDictList = new ArrayList<>();
        // 将getBaiduDictVOList中的数据迁移到baiduDictList
        for (GetBaiduDictVO vo : getBaiduDictVOList) {
            BaiduDict dict = new BaiduDict();
            dict.setId(makeOnlyId());
            dict.setWord(vo.getWord());
            dict.setBaseTranslation(vo.getBaseTranslation());
            dict.setDataOssUrl(vo.getDictFilePath());
            
            // 处理音频文件URL
            if (vo.getTtsFilePath() != null) {
                dict.setZhAudioOssUrl(vo.getTtsFilePath().get("zhFileUrl"));
                dict.setEnAudioOssUrl(vo.getTtsFilePath().get("enFileUrl"));
            }
            baiduDictList.add(dict);
        }
        dataOssUrlMapper.batchInsertBaiduDist(baiduDictList);
        return getBaiduDictVOList;
    }

    @Override
    public List<GetBaiduDictVO> isExist(String wordParam, @NotNull Boolean isBlur) {

        List<BaiduDict> baiduDictList;
        if (isBlur) {
            baiduDictList = dataOssUrlMapper.getExplainByWordBlur(wordParam);
        } else {
            baiduDictList = dataOssUrlMapper.getExplainByWord(wordParam);
        }
        List<GetBaiduDictVO> getBaiduDictVOList = new ArrayList<>();
        for (BaiduDict baiduDict : baiduDictList) {
            String word = baiduDict.getWord();
            String baseTranslation = baiduDict.getBaseTranslation();
            List<SymbolBo> symbolBoList = new ArrayList<>();
            Map<String, List<String>> exchangeWords;
            String dictFileUrl = baiduDict.getDataOssUrl();
            Map<String, String> ttsFilePath = new HashMap<>();

            // 获取音频文件路径
            ttsFilePath.put("zhFileUrl", baiduDict.getZhAudioOssUrl());
            ttsFilePath.put("enFileUrl", baiduDict.getEnAudioOssUrl());

            // 获取dict文件信息
            JSONObject dict = aliOSSUtil.getDictFile(dictFileUrl);
            JSONObject wordResult = dict.getJSONObject("word_result");
            JSONObject simpleMeans = new JSONObject();


            if (wordResult.containsKey("simple_means") && !wordResult.getStr("simple_means").isEmpty()) {
                simpleMeans = wordResult.getJSONObject("simple_means");
            }

            JSONArray symbols = new JSONArray();
            if (simpleMeans.containsKey("symbols")) {
                symbols = simpleMeans.getJSONArray("symbols");
            }
            for (int j = 0; j < symbols.size(); j++) {
                SymbolBo symbolBo = new SymbolBo();
                JSONObject symbol = symbols.getJSONObject(j);

                Map<String, String> phoneticSymbols = baiduDictUtil.getSymbols(symbol);
                symbolBo.setPhoneticSymbols(phoneticSymbols);

                Map<String, List<String>> translationsMapList = baiduDictUtil.getTranslation(symbol);
                Map<String, Map<Integer, String>> translations = new HashMap<>();
                if (!translationsMapList.isEmpty()) {
                    List<AddTranslationDTO> TranslationPartIdList = translationsMapToAddTranslationDTOList(translationsMapList);
                    translations = addService.addTranslationAll(TranslationPartIdList);
                }
                symbolBo.setTranslations(translations);

                symbolBoList.add(symbolBo);
            }

            JSONObject exchange = new JSONObject();
            if (simpleMeans.containsKey("exchange")) {
                exchange = simpleMeans.getJSONObject("exchange");
            }

            exchangeWords = baiduDictUtil.getExchange(exchange);

            GetBaiduDictVO getBaiduDictVO = GetBaiduDictVO.builder()
                    .word(word)
                    .baseTranslation(baseTranslation)
                    .symbols(symbolBoList)
                    .exchangeWords(exchangeWords)
                    .dictFilePath(dictFileUrl)
                    .ttsFilePath(ttsFilePath)
                    .build();
            getBaiduDictVOList.add(getBaiduDictVO);
        }
        return getBaiduDictVOList;
    }

    private @NotNull List<AddTranslationDTO> translationsMapToAddTranslationDTOList(@NotNull Map<String, List<String>> translationsMap) {
        List<AddTranslationDTO> addTranslationDTOList = new ArrayList<>();
        if (!translationsMap.isEmpty()) {
            for (String TranslationPart : translationsMap.keySet()) {
                List<String> translationList = translationsMap.get(TranslationPart);
                for (String translation : translationList) {
                    AddTranslationDTO addTranslationDTO = new AddTranslationDTO();
                    addTranslationDTO.setTranslation(translation);
                    // 获取词性id
                    Integer partSpeechId = getPartSpeechSIModule.getPartIdBySimple(TranslationPart);
                    if (partSpeechId == null) {
                        addPartSpeech.addPartSpeech(TranslationPart);
                        partSpeechId = getPartSpeechSIModule.getPartIdBySimple(TranslationPart);
                    }
                    addTranslationDTO.setPartSpeechId(partSpeechId);

                    addTranslationDTOList.add(addTranslationDTO);
                }
            }
        }
        return addTranslationDTOList;
    }

    /**
     * 合并翻译列表与翻译词性Id列表 （弃用方法）
     * @param translationsMapList 翻译列表
     * @param translationMapTotal 翻译词性Id列表
     * @return 合并后的结果
     */
    private @NotNull List<Map<String, Map<Integer, String>>> TranslationListToMap(@NotNull List<Map<String, List<String>>> translationsMapList, Map<String, Map<Integer, String>> translationMapTotal) {
        List<Map<String, Map<Integer, String>>> resultTranslationMap = new ArrayList<>();
        for (Map<String, List<String>> currentTranslationMap : translationsMapList) {
            Map<String, Map<Integer, String>> resultTranslationMapPart = new HashMap<>();

            currentTranslationMap.forEach((translationPart, translationList) -> {
                log.info("translationList: {}", translationList);
                if (translationMapTotal.containsKey(translationPart)) {
                    Map<Integer, String> translationMapTotalPart = translationMapTotal.get(translationPart);
                    // 通过Stream过滤保留translationList中包含的翻译值
                    Map<Integer, String> filteredMap = translationMapTotalPart.entrySet().stream()
                            .filter(entry -> translationList.contains(entry.getValue()))
                            .collect(Collectors.toMap(
                                    Map.Entry::getKey,
                                    Map.Entry::getValue
                            ));
                    // 仅当过滤后有有效内容时才添加到结果
                    if (!filteredMap.isEmpty()) {
                        resultTranslationMapPart.put(translationPart, filteredMap);
                    }
                }
            });

            resultTranslationMap.add(resultTranslationMapPart);
        }
        return resultTranslationMap;
    }
}
